package websocket

import (
	"sync"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

// UserOnlineStatus 用户在线状态
type UserOnlineStatus struct {
	UserID   string `json:"user_id"`
	UserName string `json:"user_name"`
	IsOnline bool   `json:"is_online"`
	LastSeen int64  `json:"last_seen"`
	RoomID   string `json:"room_id,omitempty"`
	RoomName string `json:"room_name,omitempty"`
}

// OnlineStatusManager 在线状态管理器
type OnlineStatusManager struct {
	users   map[string]*UserOnlineStatus
	usersMu sync.RWMutex
	server  *WebSocketServer
}

// NewOnlineStatusManager 创建新的在线状态管理器
func NewOnlineStatusManager(server *WebSocketServer) *OnlineStatusManager {
	return &OnlineStatusManager{
		users:  make(map[string]*UserOnlineStatus),
		server: server,
	}
}

// UserOnline 用户上线
func (osm *OnlineStatusManager) UserOnline(userID, userName string) {
	osm.usersMu.Lock()
	defer osm.usersMu.Unlock()

	osm.users[userID] = &UserOnlineStatus{
		UserID:   userID,
		UserName: userName,
		IsOnline: true,
		LastSeen: time.Now().Unix(),
	}

	logx.Infof("[OnlineStatusManager] 用户 %s(%s) 上线", userName, userID)
}

// UserOffline 用户下线
func (osm *OnlineStatusManager) UserOffline(userID string) {
	osm.usersMu.Lock()
	defer osm.usersMu.Unlock()

	if user, exists := osm.users[userID]; exists {
		user.IsOnline = false
		user.LastSeen = time.Now().Unix()
		logx.Infof("[OnlineStatusManager] 用户 %s(%s) 下线", user.UserName, userID)
	}
}

// GetUserStatus 获取用户状态
func (osm *OnlineStatusManager) GetUserStatus(userID string) *UserOnlineStatus {
	osm.usersMu.RLock()
	defer osm.usersMu.RUnlock()

	return osm.users[userID]
}

// GetFriendsOnlineStatus 获取好友在线状态列表
func (osm *OnlineStatusManager) GetFriendsOnlineStatus(userID string) []*UserOnlineStatus {
	// 这里应该查询用户的好友列表，暂时返回所有在线用户
	osm.usersMu.RLock()
	defer osm.usersMu.RUnlock()

	onlineUsers := make([]*UserOnlineStatus, 0)
	for _, user := range osm.users {
		if user.IsOnline && user.UserID != userID {
			onlineUsers = append(onlineUsers, user)
		}
	}

	return onlineUsers
}

// BroadcastToUser 向指定用户广播消息
func (osm *OnlineStatusManager) BroadcastToUser(userID string, msg Message) bool {
	if osm.server == nil {
		return false
	}

	// 查找用户的WebSocket连接
	osm.server.roomsMu.RLock()
	for _, room := range osm.server.rooms {
		if client, exists := room.Clients[userID]; exists {
			select {
			case client.Send <- msg.ToJSON():
				osm.server.roomsMu.RUnlock()
				return true
			default:
				// 通道已满，跳过此客户端
			}
		}
	}
	osm.server.roomsMu.RUnlock()

	// 也检查游戏房间
	osm.server.gameRoomsMu.RLock()
	for _, gameRoom := range osm.server.gameRooms {
		if client, exists := gameRoom.Clients[userID]; exists {
			select {
			case client.Send <- msg.ToJSON():
				osm.server.gameRoomsMu.RUnlock()
				return true
			default:
				// 通道已满，跳过此客户端
			}
		}
	}
	osm.server.gameRoomsMu.RUnlock()

	return false
}

// GetAllUsers 获取所有用户的状态
func (osm *OnlineStatusManager) GetAllUsers() []*UserOnlineStatus {
	osm.usersMu.RLock()
	defer osm.usersMu.RUnlock()

	users := make([]*UserOnlineStatus, 0, len(osm.users))
	for _, user := range osm.users {
		// 创建副本以避免外部修改
		userCopy := *user
		users = append(users, &userCopy)
	}

	return users
}

// SendTravelNotice 发送虚拟旅行通知
func (osm *OnlineStatusManager) SendTravelNotice(userID string, notice string) bool {
	if osm.server == nil {
		return false
	}

	// 创建虚拟旅行通知消息
	msg := Message{
		Type:    int(MessageTypeTravelNotice),
		UserID:  "system",
		Content: notice,
	}

	return osm.BroadcastToUser(userID, msg)
}
